package ru.ifmo.thesis.suite;

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.ifmo.thesis.event.Event;
import ru.ifmo.thesis.event.EventListener;
import ru.ifmo.thesis.suite.DOPSuiteRunner.NextGenerationEvolved;
import ru.ifmo.thesis.suite.DOPSuiteRunner.TaskStartedEvent;
import ru.ifmo.thesis.util.SequenceGeneratortor;

public class SuiteRunnerXSLXLogger implements SuiteRunnerLogger {
	
	private static final Logger logger = LoggerFactory.getLogger(SuiteRunnerXSLXLogger.class);

	private class NextTaskBehaviour implements EventListener {

		@Override
		public void fireEvent(Event event) {
			logger.debug("New Row");
			SuiteRunnerXSLXLogger owner = SuiteRunnerXSLXLogger.this;
			owner.cellIndex = new SequenceGeneratortor(0);
			row = sheet.createRow(rowIndex.nextValue());
		}
	}
	
	private class NextGenerationBehaviour implements EventListener {
		
		@Override
		public void fireEvent(Event e) {
			if ((cycle++) % multiplier == 0) {
				NextGenerationEvolved event = (NextGenerationEvolved) e;
				double sheduleCost = event.getSheduleCost();
				logger.debug("New value " + sheduleCost);
				Cell cell = row.createCell(cellIndex.nextValue());
				cell.setCellValue(sheduleCost);
			}
		}
	}
	
	private static final String NEW_SHEET_NAME = "new sheet";

	private Workbook workbook;

	private Sheet sheet;
	
	private Row row;

	private SequenceGeneratortor rowIndex = new SequenceGeneratortor(0);
	
	private SequenceGeneratortor cellIndex = new SequenceGeneratortor(0);
	
	private String outputFileName;

	private NextGenerationBehaviour generationListener;

	private NextTaskBehaviour taskListener;
	
	private DOPSuiteRunner runner;

	private final int multiplier;
	
	int cycle;
	
	public SuiteRunnerXSLXLogger(String XSLXFileName, DOPSuiteRunner suiteRunner, int multiplier) {
		this.outputFileName = XSLXFileName;
		this.runner = suiteRunner;
		this.multiplier = multiplier;
		this.workbook = new XSSFWorkbook();
		this.sheet = workbook.createSheet(NEW_SHEET_NAME);
		suiteRunner.addEventListener(NextGenerationEvolved.NAME, generationListener = new NextGenerationBehaviour());
		suiteRunner.addEventListener(TaskStartedEvent.NAME, taskListener = new NextTaskBehaviour());
	}

	/* (non-Javadoc)
	 * @see ru.ifmo.thesis.suite.SuiteRunnerLogger#close()
	 */
	public void close() throws IOException {
		FileOutputStream results = new FileOutputStream(outputFileName);
		workbook.write(results);
		results.close();

		workbook = null;
		sheet = null;
		row = null;
		
		rowIndex = null;
		cellIndex = null;
		
		runner.removeEventListener(NextGenerationEvolved.NAME, generationListener);
		runner.removeEventListener(TaskStartedEvent.NAME, taskListener);
	}
}
